package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicAddDTO;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.message.constant.ContactPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.ConsistencySyncRabbitMqDTO;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContactUserEntity;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContactUserModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.service.ConsistencySyncService;
import com.xbongbong.saas.service.CustomerCommunicateService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.User;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import org.elasticsearch.action.support.WriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author 魏荣杰
 *
 */
@Service
public class WorkflowContactStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {

    private static final Logger log = LoggerFactory.getLogger(WorkflowContactStrategy.class);

    @Resource
    private CustomerModel customerModel;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private UserModel userModel;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private ContactModel contactModel;
    @Resource
    private ContactUserModel contactUserModel;
    @Resource
    private MessageService messageService;
    @Resource
    private ConsistencySyncService consistencySyncService;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private CustomerCommunicateService customerCommunicateService;
    @Resource
    private ProFormHelp proFormHelp;

    @Override
    public List<Integer> type() {
        return Collections.singletonList(XbbRefTypeEnum.CONTACT.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        String corpid = workflowTransferPOJO.getCorpid();
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();
        User user = workflowTransferPOJO.getUser();
        Long newCustomerId = FastJsonHelper.getLongFromFormData(data, ContactEnum.CUSTOMER_NAME.getAttr());

        // 新建联系人消息推送
        PaasFormDataEntityExt customerEntity = customerModel.getByKey(newCustomerId, corpid);
        String customerName = "";
        if (Objects.nonNull(customerEntity)) {
            customerName = customerEntity.getData().getString(CustomerManagementEnum.NAME.getAttr());
        }
        UserEntity userEntity = userModel.getByKeyIngoreDel(user.getUserId(), corpid);
        String contactName = data.getString(ContactEnum.NAME.getAttr());
        if (!Objects.equals(workflowTransferPOJO.getIsImport(), 1)) {
            ContactEntityExt contactEntityExt = new ContactEntityExt();
            contactEntityExt.setId(dataId);
            contactEntityExt.setData(data);
            List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.CONTACT_NEW.getCode(), PushTypeEnum.CONTACT_NEW.getSubCode(), userEntity, contactEntityExt);
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(pojoData.getAppId(), pojoData.getMenuId(), pojoData.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), pojoData.getBusinessType(), pojoData.getBusinessType());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(ContactPushConstant.CONTACT_NEW_TITLE), String.format(I18nMessageUtil.getMessage(ContactPushConstant.CONTACT_NEW_CONTENT),  user.getName(), customerName, contactName), null, options);
            messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.CONTACT_NEW);
        }

        try{
            if(isNotDistributeBusinessType(workflowTransferPOJO)) {
                PaasFormEntity paasForm = proFormHelp.getPaasForm(pojoData.getFormId(), pojoData.getBusinessType(), corpid);
                String paasFormName = XbbRefTypeEnum.CONTACT.getName();
                if (Objects.nonNull(paasForm)) {
                    paasFormName = paasForm.getName();
                }

                String memo = Objects.equals(workflowTransferPOJO.getIsImport(), BasicConstant.ONE) ? CrmLogMemoConstant.DYNAMIC_USER_IMPORT : CrmLogMemoConstant.DYNAMIC_USER_ADD;
                CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
                customerDynamicAddDTO.setCorpid(corpid);
                customerDynamicAddDTO.setUserId(user.getUserId());
                customerDynamicAddDTO.setMemo(String.format(I18nMessageUtil.getMessage(memo), userEntity.getName(), paasFormName, contactName));
                customerDynamicAddDTO.setCustomerId(newCustomerId);
                customerDynamicAddDTO.setContactIds(Collections.singletonList(dataId));
                customerDynamicAddDTO.setCustomerName(customerName);
                customerDynamicAddDTO.setDataId(dataId);
                customerDynamicAddDTO.setCommunicateBusinessType(XbbRefTypeEnum.CONTACT.getCode());
                customerDynamicAddDTO.setCommunicateBusinessText(contactName);
                customerDynamicAddDTO.setLogType(ProjectLogEnum.CONTACT_CREATE.getSubType());
                customerDynamicAddDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());
                customerCommunicateService.addCustomerDynamic(customerDynamicAddDTO);
            }
        }catch (Exception e){
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowContactStrategy.save", e);
        }
        addLinkDataDynamic(workflowTransferPOJO);
        // api
        apiHook(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }


    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();
        String corpid = workflowTransferPOJO.getCorpid();

        WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(workflowTransferPOJO.getBackupDataId(), corpid);

        JSONObject oldData = workflowBackupDataEntity.getData();
        Long newCustomerId = FastJsonHelper.getLongFromFormData(data, ContactEnum.CUSTOMER_NAME.getAttr());
        Long oldCustomerId = FastJsonHelper.getLongFromFormData(oldData, ContactEnum.CUSTOMER_NAME.getAttr());


        // 同步联系人名称
        String newContactName = FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerManagementEnum.NAME.getAttr(), "");
        String opObjectName = FastJsonHelper.getStringOrDefaultFromFormData(oldData, ContactEnum.NAME.getAttr(), "");
        try {
            if (!Objects.equals(opObjectName, newContactName)) {
                ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, newContactName);
                consistencySyncService.syncContact(consistencySyncRabbitMqDTO);
            }
        }catch (Exception e){
            log.error("数据一致性同步", e);
        }

        try {
            if(isNotDistributeBusinessType(workflowTransferPOJO)) {
                String creatorId = workflowTransferPOJO.getUser().getUserId();
                UserEntity creator = userModel.getByKey(creatorId, corpid);
                PaasFormEntity paasForm = proFormHelp.getPaasForm(pojoData.getFormId(), pojoData.getBusinessType(), corpid);
                String paasFormName = XbbRefTypeEnum.CONTACT.getName();
                if (Objects.nonNull(paasForm)) {
                    paasFormName = paasForm.getName();
                }
                String creatorUserName = Objects.isNull(creator) ? "" : creator.getName();
                String communicateMemo = String.format(I18nMessageUtil.getMessage(CrmLogMemoConstant.DYNAMIC_USER_UPDATE_BASE_INFO), creatorUserName, paasFormName);
                CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
                customerDynamicAddDTO.setCorpid(corpid);
                customerDynamicAddDTO.setUserId(creatorId);
                customerDynamicAddDTO.setMemo(communicateMemo);
                customerDynamicAddDTO.setContactIds(Collections.singletonList(dataId));
                customerDynamicAddDTO.setDataId(0L);
                customerDynamicAddDTO.setCommunicateBusinessType(null);
                customerDynamicAddDTO.setCommunicateBusinessText("");
                customerDynamicAddDTO.setLogType(ProjectLogEnum.CONTACT_UPDATE.getSubType());
                customerDynamicAddDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());
                customerCommunicateService.addCustomerDynamic(customerDynamicAddDTO);
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowContactStrategy.update", e);
        }

        // api
        apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Long backupDataId = workflowTransferPOJO.getBackupDataId();
            Long dataId = workflowTransferPOJO.getData().getId();
            WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
            if (Objects.nonNull(workflowBackupDataEntity)) {
                JSONObject data = workflowBackupDataEntity.getData();

                replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

                ContactEntityExt contactEntityExt = new ContactEntityExt();
                contactEntityExt.setId(dataId);
                contactEntityExt.setCorpid(corpid);
                contactEntityExt.setData(data);
                contactEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                // 获取负责人
                contactEntityExt.setOwnerId(getOwnerId(data));
                contactEntityExt.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));
                List<ContactUserEntity> clueUserList = JSON.parseArray(data.getString(StringConstant.USER_TEAM), ContactUserEntity.class);

                FormDataUtil.removeSystemData(data);
                data.remove(StringConstant.USER_TEAM);
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                    contactEntityExt.setFlowStatus(FlowStatusEnum.PASS.getType());
                }
                contactModel.update(contactEntityExt);
                // 回退被删掉的子表单
                updateBackSubForm(contactEntityExt, corpid, IndexTypeEnum.IDX_SAAS_CONTACT_SUB);
                //回退被删掉的富文本
                updateBackRichText(taskId, workflowTransferPOJO);
                saveUserTeam(clueUserList, corpid, contactEntityExt.getId());
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowContactStrategy.updateBack error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            ContactEntityExt contactEntityExt = new ContactEntityExt();
            contactEntityExt.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                contactEntityExt.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                contactEntityExt.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            contactEntityExt.setCorpid(corpid);
            contactEntityExt.setUpdateTime(DateTimeUtil.getInt());
            contactModel.update(contactEntityExt);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;

            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_CONTACT_SUB, del);
            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);

            // 团队
            List<ContactUserEntity> contractUserList = contactUserModel.getListByContactId(corpid, dataId, null);
            if (CollectionsUtil.isNotEmpty(contractUserList)) {
                contactUserModel.deleteBatch(corpid, contractUserList, WriteRequest.RefreshPolicy.NONE, del.getDel());
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowContactStrategy.approvalFailed error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }


    private void saveUserTeam(List<ContactUserEntity> list, String corpid, Long dataId) throws XbbException {

        try {
            List<ContactUserEntity> contactUserList = contactUserModel.getListByContactId(corpid, dataId, null);
            List<Long> idList = new ArrayList<>();
            list.forEach(item->idList.add(item.getId()));

            contactUserList.removeIf(item->idList.contains(item.getId()));
            if (CollectionsUtil.isNotEmpty(contactUserList)) {

                contactUserModel.deleteBatch(corpid, contactUserList, WriteRequest.RefreshPolicy.NONE, DelEnum.DELETE.getDel());
            }
            if (CollectionsUtil.isNotEmpty(list)) {
                contactUserModel.updateBatch(list, corpid);
            }


        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowContactStrategy.saveUserTeam error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
